﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Controls;
using MockupDesigner.AppItems;
using MockupDesigner.AppItems.Commands;
using System.Windows;
using MockupDesigner.Items.Metadatas;

namespace MockupDesigner.Items
{
    public class ItemBase : ContentControl, INotifyPropertyChanged, INotifyPropertyChanging, IMetadatable
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public event PropertyChangingEventHandler PropertyChanging;

        public virtual Size GetPreferredSize()
        {
            return new Size(this.ActualWidth, this.ActualHeight);
        }

        public void OnPropertyChanged(string propertyName)
        {
            if (!(this.Parent is DesignerItem))
                return;

            CommandProcessor commandProcessor = ((DesignerCanvas)((DesignerItem)this.Parent).Parent).CommandProcessor;
            if (!commandProcessor.IsCanceling && !commandProcessor.IsRedoing && !commandProcessor.IsExecuting)
            {
                if (string.IsNullOrEmpty(propertyName))
                    throw new ArgumentNullException("propertyName");
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            (this.Parent as DesignerItem).ReloadPropertyGrid();
        }

        public void OnPropertyChanging(string propertyName, object oldValue, object newValue)
        {
            if (this.Parent as DesignerItem == null)
                return;

            CommandProcessor commandProcessor = ((DesignerCanvas)((DesignerItem)this.Parent).Parent).CommandProcessor;
            if (!commandProcessor.IsCanceling && !commandProcessor.IsRedoing && !commandProcessor.IsExecuting)
            {
                PropertyChangingEventHandler handler = PropertyChanging;
                if (handler != null)
                {
                    handler(this, new PropertyChangingEventArgs(propertyName));
                }
                commandProcessor.ExecuteCommand(new PropertyChangedCommand(), this, propertyName, newValue, oldValue);
            }
        }

        // Using a DependencyProperty as the backing store for Metadatas.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MetadatasProperty =
            DependencyProperty.Register("Metadatas", typeof(Metadata[]), typeof(ItemBase), new UIPropertyMetadata(null));

        public Metadata[] Metadatas
        {
            get { return (Metadata[])GetValue(MetadatasProperty); }
            set
            {
                if (this.Metadatas != null && value != null && this.Metadatas.Length == value.Length)
                {
                    bool different = false;
                    for (int i = 0; i < this.Metadatas.Length; i++)
                    {
                        if (this.Metadatas[i].Key != value[i].Key || this.Metadatas[i].Value != value[i].Value)
                        {
                            different = true;
                            break;
                        }
                    }
                    if (!different)
                        return;
                }
                OnPropertyChanging("Metadatas", this.Metadatas, value);
                SetValue(MetadatasProperty, value);
                OnPropertyChanged("Metadatas");
            }
        }

    }
}
